package frog

import (
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"math/rand"
	"os"
	"time"

	"gitee.com/xntk2381/frog/brain"
	"gitee.com/xntk2381/frog/egg"
	"github.com/hajimehoshi/ebiten/v2"
)

// Frog 表示青蛙
type Frog struct {
	BrainRadius float64
	Cells       []*brain.Cell
	Eye,
	MoveUp,
	MoveDown,
	MoveLeft,
	MoveRight,
	MoveRandom egg.Zone
	X, Y           int
	Energy         int64
	Egg            *egg.Egg
	Alive          bool
	MoveCount      int
	allowVariation bool
}

var (
	r       = rand.New(rand.NewSource(time.Now().UnixNano()))
	frogImg draw.Image
)

// 静态初始化块
func init() {
	// 加载青蛙图像
	var err error
	frogImg, err = loadFrogImage()
	if err != nil {
		fmt.Printf("Failed to load frog image: %v\n", err)
		// 如果加载失败，创建一个简单的绿色图像作为替代
		frogImg = image.NewRGBA(image.Rect(0, 0, 16, 16))
		green := color.RGBA{0, 255, 0, 255}
		draw.Draw(frogImg, frogImg.Bounds(), &image.Uniform{green}, image.Point{}, draw.Src)
	}
	fmt.Println("Frog image initialized successfully")
}

// loadFrogImage 加载青蛙图像
func loadFrogImage() (*image.RGBA, error) {
	// 尝试打开图像文件
	file, err := os.Open("frog.png")
	if err != nil {
		return nil, err
	}
	defer file.Close()

	// 解码图像
	img, _, err := image.Decode(file)
	if err != nil {
		return nil, err
	}
	// 确保返回的图像实现draw.Image接口
	bounds := img.Bounds()
	rgbaImg := image.NewRGBA(bounds)
	draw.Draw(rgbaImg, bounds, img, image.Point{}, draw.Src)
	return rgbaImg, nil
}

// NewFrog 创建一个新的青蛙实例
func NewFrog(x, y int, eg *egg.Egg) (*Frog, error) {
	if eg == nil || eg.CellGroups == nil {
		return nil, fmt.Errorf("illegal egg cellgroups argument: %v", eg.CellGroups)
	}

	frog := &Frog{
		X:           x,
		Y:           y,
		BrainRadius: eg.BrainRadius,
		Egg:         eg,
		Alive:       true,
		Cells:       make([]*brain.Cell, 0),
		// 初始化区域

		// 视觉细胞的输入区在脑中的坐标，先随便取 在原点附件就可以了，以后再考虑放到蛋里去进化
		Eye: egg.Zone{X: 0, Y: 0, Radius: 300},

		// 运动细胞的输入区在脑中的坐标，先随便取就可以了，以后再考虑放到蛋里去进化
		MoveUp:     egg.Zone{X: 500, Y: 50, Radius: 10},
		MoveDown:   egg.Zone{X: 500, Y: 100, Radius: 10},
		MoveLeft:   egg.Zone{X: 500, Y: 150, Radius: 10},
		MoveRight:  egg.Zone{X: 500, Y: 200, Radius: 10},
		MoveRandom: egg.Zone{X: 500, Y: 300, Radius: 10},
	}

	// 根据蛋创建脑细胞
	for _, g := range eg.CellGroups {
		for i := 0; i < g.CellQty; i++ {
			c := &brain.Cell{}
			c.Inputs = make([]*brain.Input, g.InputQtyPerCell)
			for j := 0; j < g.InputQtyPerCell; j++ {
				c.Inputs[j] = &brain.Input{}
				c.Inputs[j].Cell = c
				pos := randomPosInZone(g.GroupInputZone)
				c.Inputs[j].X = pos.X
				c.Inputs[j].Y = pos.Y
				c.Inputs[j].Radius = g.CellInputRadius
			}
			c.Outputs = make([]*brain.Output, g.OutputQtyPerCell)
			for j := 0; j < g.OutputQtyPerCell; j++ {
				c.Outputs[j] = &brain.Output{}
				c.Outputs[j].Cell = c
				pos := randomPosInZone(g.GroupInputZone)
				c.Outputs[j].X = pos.X
				c.Outputs[j].Y = pos.Y
				c.Outputs[j].Radius = g.CellOutputRadius
			}
			frog.Cells = append(frog.Cells, c)
		}
	}

	return frog, nil
}

// Active 青蛙活动，如果青蛙死亡则返回false
func (f *Frog) Active(env *Env) bool {
	if !f.Alive {
		return false
	}

	// 检查是否越界
	if f.X < 0 || f.X >= env.ENV_XSIZE || f.Y < 0 || f.Y >= env.ENV_YSIZE {
		f.Alive = false
		return false
	}

	// 移动
	for _, cell := range f.Cells {
		for _, output := range cell.Outputs {
			if f.MoveUp.Nearby(&output.Zone) {
				f.moveUp(env)
			}
			if f.MoveDown.Nearby(&output.Zone) {
				f.moveDown(env)
			}
			if f.MoveLeft.Nearby(&output.Zone) {
				f.moveLeft(env)
			}
			if f.MoveRight.Nearby(&output.Zone) {
				f.moveRight(env)
			}
			if f.MoveRandom.Nearby(&output.Zone) {
				f.moveRandom(env)
			}
		}
	}

	return true
}

// checkFoodAndEat 检查青蛙位置是否有食物并吃掉
func (f *Frog) checkFoodAndEat(env *Env) {
	eatedFood := false
	if f.X >= 0 && f.X < env.ENV_XSIZE && f.Y >= 0 && f.Y < env.ENV_YSIZE {
		if env.Foods[f.X][f.Y] > 0 {
			env.Foods[f.X][f.Y] = 0
			f.Energy += 1000 // 吃掉食物，能量增加
			eatedFood = true
		}
	}

	// 奖励逻辑可以在这里添加
	if eatedFood {
		// 这里可以添加奖励相关的代码
	}
}

// moveRandom 随机移动
func (f *Frog) moveRandom(env *Env) {
	ran := r.Intn(4)
	switch ran {
	case 0:
		f.moveUp(env)
	case 1:
		f.moveDown(env)
	case 2:
		f.moveLeft(env)
	case 3:
		f.moveRight(env)
	}
}

// moveUp 向上移动
func (f *Frog) moveUp(env *Env) {
	f.Y += 1
	if f.Y < 0 || f.Y >= env.ENV_YSIZE {
		f.Alive = false
		return
	}
	// f.MoveCount++
	f.checkFoodAndEat(env)
}

// moveDown 向下移动
func (f *Frog) moveDown(env *Env) {
	f.Y -= 1
	if f.Y < 0 || f.Y >= env.ENV_YSIZE {
		f.Alive = false
		return
	}
	// f.MoveCount++
	f.checkFoodAndEat(env)
}

// moveLeft 向左移动
func (f *Frog) moveLeft(env *Env) {
	f.X -= 1
	if f.X < 0 || f.X >= env.ENV_XSIZE {
		f.Alive = false
		return
	}
	// f.MoveCount++
	f.checkFoodAndEat(env)
}

// moveRight 向右移动
func (f *Frog) moveRight(env *Env) {
	f.X += 1
	if f.X < 0 || f.X >= env.ENV_XSIZE {
		f.Alive = false
		return
	}
	// f.MoveCount++
	f.checkFoodAndEat(env)
}

// percet1 1%的变异率
func (f *Frog) percet1(val float64) float64 {
	if !f.allowVariation {
		return val
	}
	return val * (0.99 + r.Float64()*0.02)
}

// percet5 5%的变异率
func (f *Frog) percet5(val float64) float64 {
	if !f.allowVariation {
		return val
	}
	return val * (0.95 + r.Float64()*0.10)
}

// randomPosInZone 在区域内随机生成位置
func randomPosInZone(z egg.Zone) egg.Zone {
	return egg.Zone{
		X:      z.X - z.Radius + z.Radius*2*r.Float64(),
		Y:      z.Y - z.Radius + z.Radius*2*r.Float64(),
		Radius: 0,
	}
}

// GetEnergy 返回青蛙的能量
// func (f *Frog) GetEnergy() float64 {
// 	return float64(f.Energy)
// }

// LayEgg 青蛙下蛋
func (f *Frog) LayEgg() *egg.Egg {
	// 25%的概率允许变异
	if r.Intn(100) > 25 {
		f.allowVariation = false
	} else {
		f.allowVariation = true
	}

	newEgg := &egg.Egg{}
	newEgg.BrainRadius = f.percet5(f.Egg.BrainRadius)
	cellGroups := make([]*egg.CellGroup, len(f.Egg.CellGroups))
	newEgg.CellGroups = cellGroups

	for i, oldGp := range f.Egg.CellGroups {
		cellGroup := &egg.CellGroup{}
		cellGroups[i] = cellGroup

		cellGroup.GroupInputZone = egg.Zone{
			X:      f.percet5(oldGp.GroupInputZone.X),
			Y:      f.percet5(oldGp.GroupInputZone.Y),
			Radius: f.percet5(oldGp.GroupInputZone.Radius),
		}

		cellGroup.GroupOutputZone = egg.Zone{
			X:      f.percet5(oldGp.GroupOutputZone.X),
			Y:      f.percet5(oldGp.GroupOutputZone.Y),
			Radius: f.percet5(oldGp.GroupOutputZone.Radius),
		}

		cellGroup.CellQty = int(f.percet5(float64(oldGp.CellQty)))
		cellGroup.CellInputRadius = f.percet1(oldGp.CellInputRadius)
		cellGroup.CellOutputRadius = f.percet1(oldGp.CellOutputRadius)
		cellGroup.InputQtyPerCell = int(f.percet5(float64(oldGp.InputQtyPerCell)))
		cellGroup.OutputQtyPerCell = int(f.percet5(float64(oldGp.OutputQtyPerCell)))
	}

	return newEgg
}

// Show 显示青蛙
func (f *Frog) Show(screen *ebiten.Image) {
	if !f.Alive {
		return
	}

	// 计算青蛙图像的绘制位置（居中）
	imgBounds := frogImg.Bounds()
	x := f.X - imgBounds.Dx()/2
	y := f.Y - imgBounds.Dy()/2

	// 创建绘制选项
	opts := &ebiten.DrawImageOptions{}
	opts.GeoM.Translate(float64(x), float64(y))

	// 绘制青蛙图像
	screen.DrawImage(ebiten.NewImageFromImage(frogImg), opts)
}
